package com.sc.nft.dao;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.entity.vo.MoneyRiskPageVO;
import com.sc.nft.entity.vo.WithdrawRecordVO;
import com.sc.nft.enums.WalletChannelEnum;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.entity.SandWithdrawRecord;
import com.sc.nft.mapper.SandWithdrawRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 用户提现表(sc_sand_withdraw_record)数据DAO
 *
 * @author zxy
 * @since 2023-01-01 20:36:37
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@Repository
public class SandWithdrawRecordDao extends ServiceImpl<SandWithdrawRecordMapper, SandWithdrawRecord> {


    public Page<SandWithdrawRecord> adminPage(Long userId,Integer status,String customerOrderNo, Date startTime, Date endTime, String relateionNo, int pageNo, int pageSize) {
        LambdaQueryWrapper<SandWithdrawRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(userId!=null,SandWithdrawRecord::getUserId,userId);
        wrapper.eq(status!=null,SandWithdrawRecord::getStatus,status);
        wrapper.eq(StrUtil.isNotBlank(customerOrderNo),SandWithdrawRecord::getCustomerOrderNo,customerOrderNo);
        wrapper.eq(StrUtil.isNotBlank(relateionNo),SandWithdrawRecord::getRelatedCardNo,relateionNo);
        wrapper.le(endTime!=null,SandWithdrawRecord::getCreateTime,endTime);
        wrapper.ge(startTime!=null,SandWithdrawRecord::getCreateTime,startTime);
        wrapper.orderByDesc(SandWithdrawRecord::getId);
        return page(new Page<>(pageNo,pageSize),wrapper);
    }

    public Page<SandWithdrawRecord> getPage(Long userId, Date queryTime ,WalletChannelEnum channel, int pageNo, int pageSize) {
        LambdaQueryWrapper<SandWithdrawRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SandWithdrawRecord::getUserId,userId);
        if(channel!=null){
            wrapper.eq(SandWithdrawRecord::getChannel,channel);
        }
        if(queryTime!=null){
            wrapper.between(SandWithdrawRecord::getCreateTime, DateUtil.beginOfMonth(queryTime), DateUtil.endOfMonth(queryTime));
        }
        wrapper.orderByDesc(SandWithdrawRecord::getId);
        return page(new Page<>(pageNo,pageSize),wrapper);
    }


    public List<SandWithdrawRecord> syncStatus() {
        LambdaQueryWrapper<SandWithdrawRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SandWithdrawRecord::getStatus,0);
        wrapper.eq(SandWithdrawRecord::getConfirmStatus,true);
        DateTime now = DateTime.now();
        wrapper.lt(SandWithdrawRecord::getModifyTime,DateUtil.offsetMinute(now,-30));
        wrapper.last("limit 500");
        return list(wrapper);
    }

    public void deleteByUserId(Long userId){
        LambdaUpdateWrapper<SandWithdrawRecord> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SandWithdrawRecord::getUserId,userId);
        remove(wrapper);
    }

    public List<SandWithdrawRecord> queryWithApproval(WalletChannelEnum... walletChannels){
        LambdaUpdateWrapper<SandWithdrawRecord> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(SandWithdrawRecord::getChannel,walletChannels);
        wrapper.le(SandWithdrawRecord::getSettleTime,DateTime.now());
        wrapper.eq(SandWithdrawRecord::getStatus,0);
        wrapper.eq(SandWithdrawRecord::getConfirmStatus,false);
        wrapper.last("limit 200");
        return list(wrapper);
    }


    public void success(String orderNo){
        LambdaUpdateWrapper<SandWithdrawRecord> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(SandWithdrawRecord::getStatus,1);
        wrapper.eq(SandWithdrawRecord::getCustomerOrderNo,orderNo);
        update(new SandWithdrawRecord(),wrapper);
    }

    public void fail(String orderNo,String remark){
        LambdaUpdateWrapper<SandWithdrawRecord> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(SandWithdrawRecord::getStatus,2);
        wrapper.set(SandWithdrawRecord::getRemark,remark);
        wrapper.eq(SandWithdrawRecord::getCustomerOrderNo,orderNo);
        update(new SandWithdrawRecord(),wrapper);
    }

    public BigDecimal sumWithdrawing4Hna(long userId) {
        LambdaQueryWrapper<SandWithdrawRecord> query = new LambdaQueryWrapper<>();
        query.eq(SandWithdrawRecord::getUserId, userId);
        query.eq(SandWithdrawRecord::getChannel, WalletChannelEnum.HNA);
        query.eq(SandWithdrawRecord::getConfirmStatus, false);
        query.eq(SandWithdrawRecord::getStatus,0);
        List<SandWithdrawRecord> list = this.list(query);
        BigDecimal result = BigDecimal.ZERO;
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        for (SandWithdrawRecord record : list) {
            result = result.add(record.getAmount());
        }
        return result;
    }

    public BigDecimal getToDayWithdrawAmount() {
        return baseMapper.getToDayWithdrawAmount();
    }

    public BigDecimal getToDayWithdrawAmountByDay(String day) {
        return baseMapper.getToDayWithdrawAmountByDay(day);
    }

    public Page<MoneyRiskPageVO> moneyRiskAdminPage(Long userId, String name, Integer pageNo, Integer pageSize) {
        return baseMapper.moneyRiskAdminPage(new Page<>(pageNo,pageSize),userId,name);
    }

    public Page<WithdrawRecordVO> getWithdrawRecord(WalletChannelEnum channel, Date startTime, Date endTime, String orderNo, Integer status, Boolean confirmStatus, String userTel, Page toMp) {
        return baseMapper.getWithdrawRecord(toMp, channel!=null?channel.getCode():null, startTime,endTime,orderNo,status,confirmStatus,userTel);
    }
}